package com.vca.service.service.Impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.vca.common.constants.Constants;
import com.vca.common.constants.OrderRedisConstans;
import com.vca.common.constants.WeChatConstants;
import com.vca.common.exception.VcaException;
import com.vca.common.utils.RedisUtil;
import com.vca.common.utils.RestTemplateUtil;
import com.vca.common.utils.WechatGenerateUrl;
import com.vca.common.vo.SendSmsVo;
import com.vca.common.vo.VcaMessageVo;
import com.vca.service.service.SmsService;
import com.vca.service.service.SystemConfigService;
import com.vca.service.service.WechatNewService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;

/**
 * SmsServiceImpl 接口实现
 */
@Service
public class SmsServiceImpl implements SmsService {

    public static final Logger logger = LoggerFactory.getLogger(SmsServiceImpl.class);

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private WechatNewService wechatNewService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RestTemplateUtil restTemplateUtil;

    @Value("${vca.sms.enable}")
    private Boolean enable;

    @Value("${vca.environment.active}")
    private String active;

    /**
     * @Description:订单支付成功发送短信
     * @author:chenbing
     * @date 2023/1/4 9:48
     */
    @Override
    public Boolean sendPaySuccess(String type, String name, BigDecimal payPrice, String orderId, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
            HashMap<String, Object> contentMap = new HashMap<>();
            switch (type) {
                case "event":
                    //todo: 课程/套课/讲座/展览预约成功通知
                    header.setTemplateCode("lecole_reservation_notice");
                    contentMap.put("name", name);
                    break;
                case "product":
                    //todo: 商品订单支付成功通知
                    header.setTemplateCode("lecole_payment_notice");
                    contentMap.put("payPrice", payPrice);
                    contentMap.put("orderId", orderId);
                    break;
                default:
                    break;
            }
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            header.setTemplateCode(tempId);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            switch (type) {
                case "event":
                    map.put("name", name);
                    break;
                case "product":
                    map.put("pay_price", payPrice);
                    map.put("order_id", orderId);
                    break;
                default:
                    break;
            }
            return pushSms(phone, map, tempId);
        }
    }

    public String query() {
        return "access_token=" + wechatNewService.getMiniAccessToken();
    }

    public void handleContentMap(String pageUrl, HashMap<String, Object> contentMap) {
        logger.info("active ===>{}", active);
        if (active.equals("prod")) {
            try {
                String accessToken = query();
                logger.info("access_token===>{}", accessToken);
                String link = WechatGenerateUrl.getURLScheme(Constants.API_URL, accessToken, pageUrl);
                logger.info("result response==>{}", link);
                JSONObject data = JSONObject.parseObject(link);
                if (data.containsKey("errcode") && !data.getString("errcode").equals("0")) {
                    if (data.getString("errcode").equals("40001")) {
                        redisUtil.delete(WeChatConstants.REDIS_WECAHT_MINI_ACCESS_TOKEN_KEY);
                        accessToken = wechatNewService.getMiniAccessToken();
                        link = WechatGenerateUrl.getURLScheme(Constants.API_URL, accessToken, pageUrl);
                        logger.info("result response==>{}", link);
                        JSONObject data2 = JSONObject.parseObject(link);
                        if (data2.containsKey("errcode") && !data2.getString("errcode").equals("0")) {
                            if (data2.containsKey("errmsg")) {
                                if (data2.containsKey("invalid credential, access_token is invalid or not latest")){
                                    throw new VcaException("生成URL Scheme失败：微信接口调用失败：" + data2.getString("errcode") + data2.getString("errmsg"));
                                }
                            }
                        }
                    }
                    if (data.containsKey("errmsg")) {
                        if (data.containsKey("invalid credential, access_token is invalid or not latest")){
                            throw new VcaException("生成URL Scheme失败：微信接口调用失败：" + data.getString("errcode") + data.getString("errmsg"));
                        }
                    }
                }
                String openlink = String.valueOf(data.get("openlink"));
                contentMap.put("link", openlink);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            //todo 暂时先使用假的跳转链接
            contentMap.put("link", "/page/index/index");
        }
    }

    /**
     * @Description:活动开始通知生成短信模板消息
     * @author:chenbing
     * @date 2023/1/4 10:34
     */
    @Override
    public Boolean sendActivityStart(String name, String startTime, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_event_start_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", name);
            contentMap.put("date", startTime);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            map.put("start_time", startTime);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:活动取消通知
     * @author:chenbing
     * @date 2023/1/4 10:37
     */
    @Override
    public Boolean sendActivityCancel(String name, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_event_cancel_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", name);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:商品订单取消通知
     * @author:chenbing
     * @date 2023/1/4 10:35
     */
    @Override
    public Boolean sendOrderCancelProduct(String orderId, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_cancel_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("orderId", orderId);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("order_id", orderId);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:课程/套课/讲座/展览取消预约
     * @author:chenbing
     * @date 2023/1/4 10:41
     */
    @Override
    public Boolean sendOrderAppointment(String name, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_course_cancel_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", name);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:课程/套课/讲座/展览/商品订单，未支付的订单，超时自动取消
     * @author:chenbing
     * @date 2023/1/4 10:43
     */
    @Override
    public Boolean sendOrderAutoCancel(String name, String reason, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_order_cancel_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", name);
            contentMap.put("reason", reason);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            map.put("reason", reason);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:商品订单发货通知--解
     * @author:chenbing
     * @date 2023/1/4 10:45
     */
    @Override
    public Boolean sendOrderDeliver(String name, String sfOrderNo, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_order_dispatch_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", name);
            contentMap.put("order", sfOrderNo);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            map.put("sf_order_no", sfOrderNo);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:商品订单用户手动/系统自动确认收货通知--解
     * @author:chenbing
     * @date 2023/1/4 10:47
     */
    @Override
    public Boolean sendOrderConfirmReceipt(String storeName, String orderId, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_order_confirm_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", storeName);
            contentMap.put("orderId", orderId);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("store_name", storeName);
            map.put("order_id", orderId);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:课程/套课/讲座/展览订单核销通知--解
     * @author:chenbing
     * @date 2023/1/4 10:49
     */
    @Override
    public Boolean sendOrderWriteOff(String name, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_verification_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", name);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:订单同意/拒绝退货通知--解
     * @author:chenbing
     * @date 2023/1/4 10:56
     */
    @Override
    public Boolean sendReturnGoods(String storeName, String orderId, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_return_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", storeName);
            contentMap.put("orderId", orderId);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("store_name", storeName);
            map.put("order_id", orderId);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:订单同意/拒绝退款通知--解
     * @author:chenbing
     * @date 2023/1/4 10:58
     */
    @Override
    public Boolean sendOrderRefund(String storeName, String orderId, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_reject_return_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", storeName);
            contentMap.put("orderId", orderId);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("store_name", storeName);
            map.put("order_id", orderId);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:礼品卡过期提醒
     * @author:chenbing
     * @date 2023/1/4 11:00
     */
    @Override
    public Boolean sendGiftCard(String cardNo, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_expire_reminder");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("NUMBER", cardNo);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("card_no", cardNo);
            return pushSms(phone, map, tempId);
        }
    }

    /**
     * @Description:排队状态通知--陈冰
     * @author:chenbing
     * @date 2023/1/4 11:01
     */
    @Override
    public Boolean sendLineUp(String name, String phone, String tempId, String pageUrl) {
        if (enable) {
            VcaMessageVo vcaMessageVo = new VcaMessageVo();
            VcaMessageVo.Header header = new VcaMessageVo.Header();
            header.setTo(phone);
//            header.setTemplateCode("lecole_queue_notice");
            header.setTemplateCode(tempId);
            HashMap<String, Object> contentMap = new HashMap<>();
            contentMap.put("name", name);
            handleContentMap(pageUrl, contentMap);
            vcaMessageVo.setContent(contentMap);
            vcaMessageVo.setHeader(header);
            redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(vcaMessageVo));
            return Boolean.TRUE;
        } else {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name", name);
            return pushSms(phone, map, tempId);
        }
    }


    /**
     * @Description:发送待发送消息到redis队列
     * @author:chenbing
     * @date 2023/1/4 10:03
     */
    private Boolean pushSms(String phone, HashMap<String, Object> map, String tempId) {
        String signName = systemConfigService.getValueByKeyException("sign_name");
        String accessKeyIdSms = systemConfigService.getValueByKeyException("accessKeyIdSms");
        String accessKeySecretSms = systemConfigService.getValueByKeyException("accessKeySecretSms");
        if (StrUtil.isBlank(phone) || StrUtil.isBlank(tempId) || StrUtil.isBlank(signName)) {
            throw new VcaException("参数不能为空");
//            return Boolean.FALSE;
        }
        SendSmsVo sendSmsVo = new SendSmsVo();
        sendSmsVo.setPhoneNumber(phone);
        sendSmsVo.setSignName(signName);
        sendSmsVo.setTempLateCode(tempId);
        sendSmsVo.setAccessKeyIdSms(accessKeyIdSms);
        sendSmsVo.setAccessKeySecretSms(accessKeySecretSms);
        sendSmsVo.setTemplateParam(JSONObject.toJSONString(map));
        redisUtil.lPush(OrderRedisConstans.SMS_TEMPLATE_MESSAGE, JSONObject.toJSONString(sendSmsVo));
        return Boolean.TRUE;
    }
}
